<?php
/**
 * DBShop 电子商务系统
 *
 * ==========================================================================
 * @link      https://www.dbshop.net/
 * @copyright 北京珑大钜商科技有限公司，并保留所有权利。
 * @license   https://www.dbshop.net/license.html License
 * ==========================================================================
 *
 * @author    静静的风 <baron@loongdom.cn>
 *
 */

namespace Admin\Service\Payment;

use Admin\Data\Common;
use Laminas\Config\Writer\PhpArray;
use Yansongda\Pay\Pay;

class AlipayService
{
    private $config         = [];
    private $alipayConfig   = [];

    public function __construct()
    {
        if(!$this->config) {
            $this->config = Common::getPaymentConfig('alipay');
        }

        $this->alipayConfig = [
            'app_id'        => $this->config['paymentAppId']['content'],
            'ali_public_key'=> $this->config['paymentPublicKey']['content'],
            'private_key'   => $this->config['paymentPrivateKey']['content'],

        ];
    }

    public function savePaymentConfig(array $data, $paymentConfig, $configFile)
    {
        $configArray = PaymentForm::setFormValue($paymentConfig, $data);

        $write = new PhpArray();
        $write->setUseBracketArraySyntax(true);
        $write->toFile($configFile, $configArray);

        Common::opcacheInvalidate($configFile);

        return $configArray;
    }

    public function getFormInput($paymentConfig)
    {
        return PaymentForm::createFormInput($paymentConfig);
    }

    /**
     * 订单支付
     * @param array $data
     * @return \Symfony\Component\HttpFoundation\Response
     */
    public function orderPaymentTo(array $data)
    {
        $orderInfo = $data['orderInfo'];
        $goodsArray= $orderInfo->getOrderGoods();

        $order = [
            'out_trade_no'  => $orderInfo->getOrderSn(),
            'total_amount'  => $orderInfo->getOrderAmount(),
            'subject'       => (count($goodsArray) == 1 ? $goodsArray[0]->getGoodsName() : '多商品合并购买'),
        ];

        $alipay = Pay::alipay(array_merge($this->alipayConfig, ['return_url' => $data['returnUrl'], 'notify_url' => $data['notifyUrl']]));

        //判断是否为wap端支付
        if(Common::isMobile()) return $alipay->wap($order)->send();
        return $alipay->web($order)->send();
    }

    /**
     * 发货处理
     * @param array $data
     */
    public function orderToSend(array $data)
    {

    }

    /**
     * 支付返回验证
     * @param $orderInfo
     * @return array|bool[]
     * @throws \Yansongda\Pay\Exceptions\InvalidConfigException
     * @throws \Yansongda\Pay\Exceptions\InvalidSignException
     */
    public function orderPaymentReturn($orderInfo)
    {
        try {
            $result = Pay::alipay($this->alipayConfig)->verify();
        } catch (\Exception $e) {
            exit('验证错误，您的密钥信息填写不正确！');
        }

        // 订单号：$data->out_trade_no
        // 支付宝交易号：$data->trade_no
        // 订单总金额：$data->total_amount
        if(
            $result->offsetGet('total_amount') == $orderInfo->getOrderAmount()
            && $result->offsetGet('out_trade_no') == $orderInfo->getOrderSn()
            && $orderInfo->getOrderStatus() >= Common::orderStatusCode('WAIT_GOODS_ARRIVE')
        )
        {
            return ['paymentStatus' => true, 'orderAmount' => $result->offsetGet('total_amount')];
        }
        return ['paymentStatus' => false];
    }

    /**
     * 支付异步通知
     * @param $orderInfo
     * @return array
     */
    public function orderPaymentNotify($orderInfo)
    {
        $alipay = Pay::alipay($this->alipayConfig);
        try {
            $result = $alipay->verify();
            // 请自行对 trade_status 进行判断及其它逻辑进行判断，在支付宝的业务通知中，只有交易通知状态为 TRADE_SUCCESS 或 TRADE_FINISHED 时，支付宝才会认定为买家付款成功。
            // 1、商户需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号；
            // 2、判断total_amount是否确实为该订单的实际金额（即商户订单创建时的金额）；
            // 3、校验通知中的seller_id（或者seller_email) 是否为out_trade_no这笔单据的对应的操作方（有的时候，一个商户可能有多个seller_id/seller_email）；
            // 4、验证app_id是否为该商户本身。
            // 5、其它业务逻辑情况
            if(
                in_array($result->offsetGet('trade_status'), ['TRADE_SUCCESS', 'TRADE_FINISHED'])
                && $result->offsetGet('out_trade_no') == $orderInfo->getOrderSn()
                && $result->offsetGet('total_amount') == $orderInfo->getOrderAmount()
            )
            {
                //查看是否已经支付完毕
                if($orderInfo->getOrderStatus() >= Common::orderStatusCode('WAIT_GOODS_ARRIVE')) return ['finishPay' => true, 'orderAmount' => $result->offsetGet('total_amount'), 'sendMessage' => 'success'];

                return ['paymentStatus' => true, 'outTradeNo' => $result->offsetGet('out_trade_no'), 'orderAmount' => $result->offsetGet('total_amount'), 'sendMessage' => 'success'];
            }
        } catch (\Exception $e) {
            //$e->getMessage();
        }
        //return $alipay->success()->send();
        return ['paymentStatus' => false, 'sendMessage' => ''];
    }

    /**
     * 支付
     * @param array $data
     * @return \Symfony\Component\HttpFoundation\Response
     */
    public function paymentTo(array $data)
    {
        $info = [
            'out_trade_no'  => $data['sn'],
            'total_amount'  => $data['amount'],
            'subject'       => $data['subject']
        ];
        $alipay = Pay::alipay(array_merge($this->alipayConfig, ['return_url' => $data['returnUrl'], 'notify_url' => $data['notifyUrl']]));

        //判断是否为wap端支付
        if(Common::isMobile()) return $alipay->wap($info)->send();
        return $alipay->web($info)->send();
    }

    /**
     * 支付返回
     * @param array $data
     * @return array|bool[]
     * @throws \Yansongda\Pay\Exceptions\InvalidConfigException
     * @throws \Yansongda\Pay\Exceptions\InvalidSignException
     */
    public function paymentReturn(array $data)
    {
        $result = Pay::alipay($this->alipayConfig)->verify();
        if(
            $result->offsetGet('total_amount') == $data['amount']
            && $result->offsetGet('out_trade_no') == $data['sn']
            && $data['status'] >= 20
        )
        {
            return ['paymentStatus' => true, 'amount' => $result->offsetGet('total_amount')];
        }
        return ['paymentStatus' => false];
    }

    /**
     * 支付异步
     * @param array $data
     * @return array
     */
    public function paymentNotify(array $data)
    {
        $alipay = Pay::alipay($this->alipayConfig);
        try {
            $result = $alipay->verify();
            if(
                in_array($result->offsetGet('trade_status'), ['TRADE_SUCCESS', 'TRADE_FINISHED'])
                && $result->offsetGet('out_trade_no') == $data['sn']
                && $result->offsetGet('total_amount') == $data['amount']
            )
            {
                //查看是否已经支付完毕
                if($data['status'] >= 20) return ['finishPay' => true, 'amount' => $result->offsetGet('total_amount'), 'sendMessage' => 'success'];

                return ['paymentStatus' => true, 'amount' => $result->offsetGet('total_amount'), 'sendMessage' => 'success'];
            }
        } catch (\Exception $e) {
            //$e->getMessage();
        }
        return ['paymentStatus' => false, 'sendMessage' => ''];
    }
}